/*globals YUI database */
/*jslint white: true, browser: true, onevar: false, undef: true, nomen: false, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, newcap: true, immed: true, strict: false */

/**
 *
 */
YUI.add('v3-dialog-stack', function (Y) {
    var L = Y.Lang;

    // zIndex comparator
    var byZIndexDesc = function (a, b) {
        if (!a || !b || !a.hasImpl(Y.WidgetStack) || !b.hasImpl(Y.WidgetStack)) {
            return 0;
        } else {
            var aZ = a.get("zIndex");
            var bZ = b.get("zIndex");

            if (aZ > bZ) {
                return -1;
            } else if (aZ < bZ) {
                return 1;
            } else {
                return 0;
            }
        }
    };

    var mouseDownHandler = function (event) {
        var dialog = Y.Widget.getByNode(event.target);
        this.bringToTop(dialog);
    };

    var idSeed = 0;

    var createContainer = function () {
        var container = Y.Node.create('<div class="yui3-dialog-stack" id="dialog-stack-' + idSeed + '"></div>');
        Y.one('body').append(container);
        return container;
    };

    var removeFromStack = function (event, dialog) {
        var dialogStack = this.dialogStack,
            index = Y.Array.indexOf(dialogStack, dialog);

        if (index > -1) {
            dialogStack.splice(index, 1);
        }
    };

    var DialogStack = function (config) {
        idSeed += 1;
        config = config || {};
        this.container = config.container || createContainer();
        this.dialogStack = [];
    };

    DialogStack.prototype = {
        'newDialog': function (config) {
            var dialog = this.findInStack(config.id);
            if (dialog) {
                this.bringToTop(this.dialogStack, dialog);
            } else {
                dialog = new Y.V3_Dialog(config);
                dialog.after('renderedChange', function (event) {
                    this.addDialog(dialog);
                }, this);
            }

            return dialog;
        },

        'inStack': function (id) {
            return L.isObject(this.findInStack(this.dialogStack, id));
        },

        'findInStack': function (id) {
            var dialogStack = this.dialogStack,
                dialog,
                index,
                len = dialogStack.length;

            for (index = 0; index < len; index += 1) {
                dialog = dialogStack[index];
                if (dialog.get('id') === id) {
                    return dialog;
                }
            }

            return null;
        },

        'bringToTop': function (dialog) {
            var dialogStack = this.dialogStack;
            dialogStack.sort(byZIndexDesc);
            var highest = dialogStack[0];
            if (highest !== dialog) {
                var highestZ = highest.get("zIndex");
                var dialogZ = dialog.get("zIndex");

                dialog.set("zIndex", highestZ);
                highest.set("zIndex", dialogZ);
            }
        },

        'addDialog': function (dialog) {
            if (Y.Array.indexOf(this.dialogStack, dialog) === -1) {
                var dialogNode = dialog.getNode();
                this.dialogStack.push(dialog);
                this.container.append(dialogNode);
                dialogNode.on('mousedown', mouseDownHandler, this);
                dialog.on('destroy', removeFromStack, this, dialog);
            } else {
                this.bringToTop(dialog);
            }
        }
    };

    Y.V3_Dialog_Stack = DialogStack;
}, '0.1', {
    'requires': ['v3-dialog']
});
